package tech.yixiyun.framework.kuafu.log;


import tech.yixiyun.framework.kuafu.config.AppConfig;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.json.JsonConfiguration;
import org.apache.logging.log4j.core.config.json.JsonConfigurationFactory;
import org.apache.logging.log4j.util.Supplier;

import java.io.ByteArrayInputStream;
import java.io.IOException;

/**
 * 日志实例，实现了LOG接口，通过ServiceLoader机制，会被tomcat的LogFactory加载，替换默认的日志实现。
 * @author Boolone
 * @date 2019/12/15
 */
public class LOGGER  {
    private static final Logger INSTANCE ;
    static  LoggerContext context = null;
    static {
        //Log4j2 开启控制台打印带颜色
        System.setProperty("log4j.skipJansi", "false");

        //根据配置文件加载日志配置
        String config = AppConfig.getAsString("system.run.logger.configuration");
        config = "{\"configuration\":"+config+"}";
        ByteArrayInputStream is = new ByteArrayInputStream(config.getBytes());
        try {
            context = LoggerContext.getContext(false);
            JsonConfiguration configuration = (JsonConfiguration) new JsonConfigurationFactory().getConfiguration(context, new ConfigurationSource(is));
            configuration.start();
            context.setConfiguration(configuration);
            String loggerName = AppConfig.getAsString("system.run.logger.default");
            INSTANCE = context.getLogger(loggerName);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 动态的改变日志级别
     * @param level
     */
    public static void changeLevel(Level level) {
        INSTANCE.setLevel(level);
    }


    /**
     * 打印 统一标题格式 ******** xxx ********
     * @param message
     */
    public static void debugTitle(final String message) {
        INSTANCE.debug("********  {}  ********", message);
    }
    public static void debug(final CharSequence message) {
        INSTANCE.debug(message);
    }

    public static void debug(final CharSequence message, final Throwable t) {
        INSTANCE.debug(message, t);
    }

    public static void debug(final Object message) {
        INSTANCE.debug(message);
    }

    public static void debug(final Object message, final Throwable t) {
        INSTANCE.debug(message, t);
    }

    public static void debug(final String message) {
        INSTANCE.debug(message);
    }

    public static void debug(final String message, final Object... params) {
        INSTANCE.debug(message, params);
    }

    public static void debug(final String message, final Throwable t) {
        INSTANCE.debug(message, t);
    }

    public static void debug(final Supplier<?> msgSupplier) {
        INSTANCE.debug(msgSupplier);
    }

    public static void debug(final Supplier<?> msgSupplier, final Throwable t) {
        INSTANCE.debug(msgSupplier, t);
    }




    public static void info(final CharSequence message) {
        INSTANCE.info(message);
    }
    public static void info(final CharSequence message, final Throwable t) {
        INSTANCE.info(message, t);
    }

    public static void info(final Object message) {
        INSTANCE.info(message);
    }

    public static void info(final Object message, final Throwable t) {
        INSTANCE.info(message, t);
    }

    public static void info(final String message) {
        INSTANCE.info(message);
    }

    /**
     * 打印 统一标题格式 ******** xxx ********
     * @param message
     */
    public static void infoTitle(final String message) {
        INSTANCE.info("********  {}  ********", message);
    }


    public static void info(final String message, final Object... params) {
        INSTANCE.info(message, params);
    }

    public static void info(final String message, final Throwable t) {
        INSTANCE.info(message, t);
    }

    public static void info(final Supplier<?> msgSupplier) {
        INSTANCE.info(msgSupplier);
    }

    public static void info(final Supplier<?> msgSupplier, final Throwable t) {
        INSTANCE.info(msgSupplier, t);
    }



    /**
     * 打印 统一标题格式 ******** xxx ********
     * @param message
     */
    public static void warnTitle(final String message) {
        INSTANCE.warn("********  {}  ********", message);
    }
    public static void warn(final CharSequence message) {
        INSTANCE.warn(message);
    }
    public static void warn(final CharSequence message, final Throwable t) {
        INSTANCE.warn(message, t);
    }

    public static void warn(final Object message) {
        INSTANCE.warn(message);
    }

    public static void warn(final Object message, final Throwable t) {
        INSTANCE.warn(message, t);
    }

    public static void warn(final String message) {
        INSTANCE.warn(message);
    }

    public static void warn(final String message, final Object... params) {
        INSTANCE.warn(message, params);
    }

    public static void warn(final String message, final Throwable t) {
        INSTANCE.warn(message, t);
    }

    public static void warn(final Supplier<?> msgSupplier) {
        INSTANCE.warn(msgSupplier);
    }

    public static void warn(final Supplier<?> msgSupplier, final Throwable t) {
        INSTANCE.warn(msgSupplier, t);
    }






    public static void error(final CharSequence message) {
        INSTANCE.error(message);
    }
    public static void error(final CharSequence message, final Throwable t) {
        INSTANCE.error(message, t);
    }

    public static void error(final Object message) {
        INSTANCE.error(message);
    }

    public static void error(final Object message, final Throwable t) {
        INSTANCE.error(message, t);
    }

    public static void error(final String message) {
        INSTANCE.error(message);
    }

    public static void error(final String message, final Object... params) {
        INSTANCE.error(message, params);
    }

    public static void error(final Throwable t) {
        INSTANCE.error(t.getMessage());
    }
    public static void error(final String message, final Throwable t) {
        INSTANCE.error(message, t);
    }

    public static void error(final Supplier<?> msgSupplier) {
        INSTANCE.error(msgSupplier);
    }

    public static void error(final Supplier<?> msgSupplier, final Throwable t) {
        INSTANCE.error(msgSupplier, t);
    }






    public static void fatal(final CharSequence message) {
        INSTANCE.fatal(message);
    }
    public static void fatal(final CharSequence message, final Throwable t) {
        INSTANCE.fatal(message, t);
    }

    public static void fatal(final Object message) {
        INSTANCE.fatal(message);
    }

    public static void fatal(final Object message, final Throwable t) {
        INSTANCE.fatal(message, t);
    }

    public static void fatal(final String message) {
        INSTANCE.fatal(message);
    }

    public static void fatal(final String message, final Object... params) {
        INSTANCE.fatal(message, params);
    }

    public static void fatal(final String message, final Throwable t) {
        INSTANCE.fatal(message, t);
    }

    public static void fatal(final Supplier<?> msgSupplier) {
        INSTANCE.fatal(msgSupplier);
    }

    public static void fatal(final Supplier<?> msgSupplier, final Throwable t) {
        INSTANCE.fatal(msgSupplier, t);
    }




    public static void trace(final CharSequence message) {
        INSTANCE.trace(message);
    }
    public static void trace(final CharSequence message, final Throwable t) {
        INSTANCE.trace(message, t);
    }

    public static void trace(final Object message) {
        INSTANCE.trace(message);
    }

    public static void trace(final Object message, final Throwable t) {
        INSTANCE.trace(message, t);
    }

    public static void trace(final String message) {
        INSTANCE.trace(message);
    }

    public static void trace(final String message, final Object... params) {
        INSTANCE.trace(message, params);
    }

    public static void trace(final String message, final Throwable t) {
        INSTANCE.trace(message, t);
    }

    public static void trace(final Supplier<?> msgSupplier) {
        INSTANCE.trace(msgSupplier);
    }

    public static void trace(final Supplier<?> msgSupplier, final Throwable t) {
        INSTANCE.trace(msgSupplier, t);
    }



}
